/**
 * @author Mie Plougstrup, Anders Abildgaard, Bo Stokholm 
 * @Version 16-12-2014
 */

package ctrLayer;

import java.sql.Date;
import java.util.ArrayList;

import modelLayer.Booking;
import modelLayer.ChartecCode;
import modelLayer.Disposition;
import modelLayer.DispositionList;
import modelLayer.Driver;
import modelLayer.Trailer;
import dbLayer.DbDisposition;
import dbLayer.DbDispositionList;
import dbLayer.DbMaxId;

public class CtrDisposition {
	private DbDispositionList dbDispositionList;
	private DbDisposition dbDisposition;
	private CtrBooking ctrBooking;
	private CtrDriver ctrDriver;
	private CtrTrailer ctrTrailer;
	private CtrChartecCode ctrChartecCode;

	/**
	 * Constructor - Initialized fields.
	 */
	public CtrDisposition() {
		dbDispositionList = new DbDispositionList();
		dbDisposition = new DbDisposition();
		ctrBooking = new CtrBooking();
		ctrDriver = new CtrDriver();
		ctrTrailer = new CtrTrailer();
		ctrChartecCode = new CtrChartecCode();
	}

	/**
	 * Method for creating a dispositionList object and inserting it into the database.
	 * 
	 * @param Date 				The shippingDate the user selected.
	 * @return 					The newly created object.
	 * @throws Exception
	 */
	public DispositionList createDispList(Date shippingDate) throws Exception {
		DispositionList dplObj = new DispositionList(shippingDate);
		int id = DbMaxId.getMaxID("dispListId", "dispositionList") + 1;
		dplObj.setDispListId(id);
		dbDispositionList.insert(dplObj);
		return dplObj;
	}

	/**
	 * Method for creating a disposition, adding it to a dispositionList and inserting it into the database.
	 * 
	 * @param chartecNo			Chartec number as input from UI.
	 * @param trailerId			The id of the selected trailer.
	 * @param driverId			The id of the selected driver.
	 * @param dispList			The selected dispositionList object.
	 * @param deliveryNo		Delivery number as input from UI.
	 * @return 					Disposition object
	 * @throws Exception
	 */
	public Disposition addDisposition(DispositionList dispList, int chartecNo, int trailerId, int driverId, String deliveryNo) throws Exception {
		String first4 = "" + chartecNo;
		first4 = first4.substring(0, 4);
		int chartecCodeId = Integer.parseInt(first4);
		ChartecCode ctc = ctrChartecCode.retrieveChartecCode(chartecCodeId);
		Trailer t = ctrTrailer.retrieveTrailer(trailerId);
		Driver d = ctrDriver.retrieveDriver(driverId);
		Disposition disp = new Disposition(chartecNo, d, t, ctc, deliveryNo);
		disp.setDispId(DbMaxId.getMaxID("dispId", "disposition") + 1);
		dispList.addDisposition(disp);
		dbDisposition.insertIntoDisposition(disp, dispList.getDispListId());
		return disp;
	}

	/**
	 * Method for adding a booking to a disposition.
	 * Saves it in the database along with the sequence of how it was added.
	 * 
	 * @param disp			The disposition object.
	 * @param booking		The booking object.
	 * @throws Exception
	 */
	public void addBooking(Disposition disp, Booking booking) throws Exception {
		Disposition d = disp;
		int sequenceNo = d.addBooking(booking);
		dbDisposition.insertIntoBookingSequence(d.getDispId(), sequenceNo, booking.getBookingId());
	}

	/**
	 * Method for removing a booking from a disposition.
	 * Updates in the database the changes in the sequence of bookings.
	 *
	 * @param disp			The disposition object.
	 * @param sequenceNo	The sequenceNo of the booking to be removed.
	 * @throws Exception
	 */
	public void removeBooking(Disposition disp, int sequenceNo) throws Exception{
		disp.removeBooking(sequenceNo);
		dbDisposition.updateBookingSequence(disp);
	}

	/**
	 * Method for moving a booking up in the list.
	 * Updates in the database the changes in the sequence of bookings.
	 * 
	 * @param disp			The disposition object.
	 * @param sequenceNo	The sequenceNo of the booking to be moved.
	 * @throws Exception 
	 */
	public void moveBookingUp(Disposition disp, int sequenceNo) throws Exception {
		disp.refactorSequenceUp(sequenceNo);
		dbDisposition.updateBookingSequence(disp);
	}

	/**
	 * Method for moving a booking down in the list.
	 * Updates in the database the changes in the sequence of bookings.
	 * 
	 * @param disp			The disposition object.
	 * @param sequenceNo	The sequenceNo of the booking to be moved.
	 * @throws Exception 
	 */
	public void moveBookingDown(Disposition disp, int sequenceNo) throws Exception {
		disp.refactorSequenceDown(sequenceNo);	
		dbDisposition.updateBookingSequence(disp);
	}

	/**
	 * Method for retrieving a disposition by its Id.
	 * 
	 * @param int dispId
	 * @return Disposition object
	 */
	public Disposition retrieveDisp(int dispId) {
		return dbDisposition.retrieveById(dispId, true);
	}

	/**
	 * Method for updating disposition data in the database.
	 * 
	 * @param disp
	 * @param int dispListId
	 * @throws Exception
	 */
	public void updateDisp(Disposition disp, DispositionList dispList) throws Exception {
		dbDisposition.update(disp, dispList.getDispListId());
	}

	/**
	 * Method for deleting a disposition.
	 * 
	 * @param disp
	 * @throws Exception
	 */
	public void deleteDisp(Disposition disp) throws Exception {
		dbDisposition.deleteFromDisposition(disp);
	}

	/**
	 * Method for retrieving a dispositionList. 
	 * 
	 * @param dispListId 		The id of the specific dispositionList
	 * @return 					The specific dispositionList object.
	 */
	public DispositionList retrieveDispList(int dispListId, boolean associate) {
		return dbDispositionList.retrieveById(dispListId, associate);
	}

	/**
	 * Method for retrieving all undone dispositionList objects.
	 * 
	 * @return 					A list of all the undone objects.
	 */
	public ArrayList<DispositionList> retrieveUndoneLists(boolean associate) {
		return dbDispositionList.retrieveUndone(associate);
	}

	/**
	 * Method for updating a dispositionList.
	 * 
	 * @param dispList
	 */
	public void updateDispList(DispositionList dispList) {
		dbDispositionList.update(dispList);
	}

	/**
	 * Method for ending a dispositionList.
	 * 
	 * @param dispList	The dispositionList object.
	 */
	public void endDispList(DispositionList dispList) {
		dispList.setDone(true);
		dbDispositionList.update(dispList);
	}


	/**
	 * Method for deleting a dispositionList.
	 * 
	 * @param dispList	The dispositionList object.
	 */
	public void deleteDispList(DispositionList dispList) {
		dbDispositionList.delete(dispList);
	}

	/**
	 * Method for printing a dispositionList with all dispositions.
	 * 
	 * @param dispList
	 */
	public void printListToFile(DispositionList dispList) {
		dispList.printToFile();
	}

	/**
	 * Method for printing a dispositionList with the dispositions that is handled in the storage.
	 * 
	 * @param dispList
	 */
	public void printListToFileStorage(DispositionList dispList) {
		dispList.printToStorageFile();
	}

}
